Skip to content

Git3 Compat + gix speedup for GitPython - #2274

Merged
Byron merged 22 commits into
mainfrom
gix-backend
Oct 24, 2026
Merged

Byron merged 22 commits into
mainfrom
gix-backend

Conversation

@Byron

@Byron Byron commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Tasks

  • refackiew - no need actually, but perusing I shall
  • Update to latest GixPython
  • update readme to talk about GixPython
Details

Created by Codex on behalf of Byron. Byron will review before this is ready to merge.

Summary

[!IMPORTANT]
This PR will become GitPython 3.3 some weeks before Git 3 is officially released in March.
Users can already test and run their software against this branch. Please report compatibility problems and provide feedback here in this PR.

To try it with Git 2.52 or newer installed:

python -m pip install --upgrade "git+https://github.com/gitpython-developers/GitPython.git@gix-backend"

GitPython now delegates repository discovery, configuration, references, reflogs, object storage, tree construction, index operations, and revision parsing to guarded Git commands. The default backend supports SHA-1 and SHA-256 objects with either files or reftable reference storage, without interpreting Git's binary storage formats in Python.

The Python GitDB storage implementation is removed; git.GitDB and git.db.GitDB remain compatibility aliases for the managed GitCmdObjectDB backend. Raw repo.git command access remains available. The migration notes in changes.rst describe the API changes and differences in Git CLI behavior.

Changes

1. Git CLI implementation of the GitPython API surface

The ordinary installation implements the supported GitPython API through guarded git.cmd.Git calls. Git owns repository storage and format handling, including SHA-1/SHA-256 objects and files/reftable references. This removes Python storage-format parsing from the default backend while retaining common documented workflows and raw repo.git access. Removed low-level APIs have replacements documented in the changelog. The existing context and migration notes below describe safety controls and low-level API changes.

2. GixPython implementation for better performance

The optional GitPython[gix] installation uses the published GixPython==0.2.0 release on CPython 3.11+. GitPython selects it automatically when the gix module is importable; the ordinary installation continues to support Python 3.8+. Set GIT_PYTHON_BACKEND=cli or GIT_PYTHON_BACKEND=gix before importing GitPython to select a backend explicitly. To try the native backend:

python -m pip install --upgrade "GitPython[gix] @ git+https://github.com/gitpython-developers/GitPython.git@gix-backend"

Supported library-managed operations use Gitoxide through GixPython's gix API for object reads/writes, revision and graph queries, tree enumeration and construction, index reads, references and reflogs, commit creation/statistics, tree diffs, status, untracked files, and ignore matching. Unsupported formats and options retain the guarded CLI implementation. In particular, reftable and extensions.compatObjectFormat repositories currently use Git. Native mutation failures are reported without attempting a second CLI mutation. Private index edits and tag object storage use Git until Gix exposes strict validation; index state in Python consists only of opaque file bytes. Commit/tag reads use structured Gix decoders where compatible; commit text requiring encoding conversion uses Git. Public repo.git commands retain their CLI behavior.

Historical local measurements, using official GixPython 0.1.0 on CPython 3.12.14, macOS arm64, before the 0.2.0 fixture migration:

Workload Git CLI GixPython Observed speedup
Full optimized suite, with coverage 755.78 s (12m36s) 404.61 s (6m45s) 1.87×
Top-level submodule tests, without coverage 178.75 s 88.63 s 2.02×
Tree tests, without coverage 3.86 s 1.66 s 2.33×

These are individual local validation runs, not statistical benchmarks or a guarantee for every application. The full suites collect different backend-specific tests; the focused selections overlap. See the backend guide and performance journal for conversion coverage, remaining CLI cases, reproduction details, and the GixPython/Gitoxide follow-up ledger (GIX-1 through GIX-30). Repository handles are now retained and refreshed through the shared accessor; the historical timings above predate that work.

3. Scripted test fixtures and CI

Both backend test suites now require GixPython 0.2.0 for gix.testtools. Initial repository and filesystem states live in Bash scripts under tests/fixtures. Read-only tests reuse cached output; mutating tests receive independent writable copies. Scripts re-execute only when their contents cannot be copied or relocated correctly, including link/permission cases and private absolute paths. Operations under test remain in Python, and Git CLI behavior defines expectations for both backends. Generated fixture caches and archives are ignored; no generated archives are checked in.

Full fixture suites run on Python 3.11+ with Bash and Git 2.52+. Python 3.8–3.10 retain installation/import smoke coverage, including Cygwin's Python 3.9 job. CI installs and imports gix.testtools for both backend selections, explicitly selects the backend, and prepares Rust and build caches where GixPython must be built from its released source distribution.

Historical fixture measurements with GixPython 0.1.0: on the same local coverage-enabled suite, fixture optimizations reduced wall time from 757.85 s (12m38s) to 404.61 s (6m45s): 353.24 s saved, 46.6% less time, about 1.87× faster. CLI fallback decisions decreased from 39,002 to 21,402; these counters do not count every Git subprocess. This is the before/after fixture improvement, separate from the backend comparison above. The changes reduce repeated work in the CI suites; the quoted timings are local measurements, not a hosted GitHub Actions before/after benchmark. No matching pre-optimization full CLI run was recorded.

The branch also adds released downstream compatibility checks for LangChain, MLflow, Bandit, SWE-bench, and DataHub, plus reproducible local test execution and backend-operation reports.

Context

The goal is to support Git's object and reference formats while reducing the attack surface of Python implementations and limiting argument injection and unintended CLI side effects.

  • Managed calls use git.cmd.Git, existing unsafe option/protocol checks, validated operands, and framed stdin records. Shell execution and option reordering past protective flags are rejected. Persistent cat-file requests use NUL framing.
  • Managed plumbing suppresses implicit hooks, filesystem monitors, maintenance, and lazy fetching. Diffs disable external diff and text conversion; blame disables text conversion by default. Explicit commit hooks use git hook run. Signing/editor options and custom archive format commands require an unsafe-options opt-in.
  • Existing Git worktree conversions remain intentional: status and worktree diffs can run clean filters; checkout, clone, and archive can run smudge filters. Index staging continues to store raw content.
  • Common documented workflows remain. Git manages semantic index entries and temporary indexes, references and reflogs, configuration syntax/locking, remote results, and submodule lifecycle operations. Discovery and cloning respect worktree storage boundaries, and submodule reconnection preserves the child repository's object and reference formats.
  • Known command outcomes retain established exceptions where distinguishable; other failures expose GitCommandError with Git's status and diagnostics.
  • Low-level APIs that cannot be represented faithfully through Git are removed or restricted. These include binary index/tree helpers, raw reflog rewriting and oldhexsha, precompressed object streams and custom object-output writers, Submodule.rename(), and direct Repo.alternates mutation. Configuration follows Git syntax and no longer subclasses RawConfigParser. Detailed replacements and limitations are in the changelog.

The change also updates documentation, format/backend and injection regressions, the minimum-Git CI job, and fuzz harnesses. Obsolete binary-parser, deprecation and timing-only tests have been removed. Happy paths, Python glue failures and representative compatibility regressions remain; the maintained backend benchmark checks parity and CLI budgets. The release announcement above describes the planned release; this PR does not change VERSION yet.

CI follow-up handles platform path conventions and rejects unsupported index filenames before changing the original index. Submodule updates now close their internally opened repositories, preventing retained log records from keeping Windows checkouts open through Git processes. Cygwin builds the supported Git version in its normal installation layout and verifies detection before installation/import smoke checks.

Migration details and historical validation

The index lifecycle now materializes deferred bytes into private files, verifies that Git retained requested entries, and publishes atomically. Failed ordinary edits preserve pending/published state; hook edits survive failures without advancing HEAD. IndexFile.entries remains available as an immutable read snapshot; use iter_entries(), entry() and explicit index edits. Direct mapping mutation remains unsupported. Textual date parsing and final trailer extraction use Git. See the migration notes for removed environment-expansion/error-hiding switches and changed date/trailer behavior.

Historical validation at earlier revisions: on macOS with Git 2.54.0, the retained suite passed with 1,767 tests on Gix and 1,672 on CLI, plus focused regressions on both. All five downstream profiles passed on both backends. All 14 benchmark result digests matched and existing Gix CLI ceilings passed; concurrent fast timing samples do not establish a speed change. Lint, typing and documentation checks passed locally. CI follow-up fixes the Bash 3.2 condition on macOS, removes the empty historical Cygwin performance split, makes path and command fixtures respect Windows configuration, closes a test-owned submodule parent before removal, and isolates partial-write failure injection to locked publication. Focused regressions passed locally with both backends. All 64 hosted checks passed on 17a316c, including the complete Windows matrix, Gix on Ubuntu/macOS/Windows, downstream compatibility, backend parity and CLI ceilings, and Cygwin (1,691 passed, 20 skipped, 11 xfailed).

Earlier CI validation

All 64 hosted checks passed for 781c620 on October 15, 2026. This includes the complete Windows matrix, Gix on Ubuntu/macOS/Windows, Python 3.8–3.10 installation/import checks, Cygwin smoke coverage, Alpine, the minimum-Git job, all five downstream compatibility profiles, backend parity and CLI-process ceilings, and the configured quality checks.

Windows Python 3.12 passed 1,674 CLI tests and 1,772 Gix tests, with 61 passing subtests on each backend. The final fixture correction also passed all 40 commit tests and 21 subtests locally on CLI, then Gix, plus the changed files' pre-commit hooks. Git remains the text baseline: malformed UTF-16 fixtures now force conversion failure, with raw-size assertions, rather than assuming stable output after conversion erases Git's header delimiters. Production behavior is unchanged by that correction.

The measurements in earlier sections remain historical; this CI run does not establish a new timing claim. Python 3.8–3.10 receive smoke coverage rather than the GixPython-dependent fixture suites.

Expanded downstream audit and current head

46303c88 consolidates the four audit records into one top commit, above the feature and twelve compatibility fixes. The audit index links reports and JSON manifests for 115 distinct projects, covering every identified current declared consumer within the September 2026 top-15,000 PyPI snapshot. The covered 348,530,835 monthly distribution requests include extras and repeat downloads; they do not measure GitPython installations or unique users. Original known-user additions and missing metadata prevent a strict popularity top-115 claim. Selected paths, upstream mocks, isolated helpers, omitted application stacks and CLI fallbacks remain explicitly disclosed.

The fixes restore immutable index readers, global -C selection, separate-Git-directory checkout context, the managed GitDB selector, local tracking branches, revision tree/path diagnostics, explicit literal-path construction, editable/build version behavior, historical Union/Optional imports and nonempty config section assignment. Current CI repairs use the Python 3.8-compatible typing.Mapping, make the guaranteed first discovery-loop iteration explicit, and compare Windows test checkout paths by filesystem identity.

Remaining actionable gaps are documented: Kas's empty-section creation needs a native section-edit API (downstream can use set_value() directly); sbxloop's constructor subclass needs supported metadata/include controls or migration; index mapping writes remain unsupported; ambiguous bare/mirror fetch results need full destination identities from Git's fetch --porcelain. Gix fetch remains a CLI fallback until its binding exposes compatible per-ref outcomes. Other retained downstream failures are distinguished from new GitPython regressions by released-baseline comparisons.

Local validation for the CI repairs passed: Python 3.8 import and evaluated annotations, 90 config/downstream tests and 146 repository/downstream tests plus 14 subtests on each backend, followed by 40 final downstream regressions per backend; CLI ran first. Ruff lint/format, mypy and basedpyright pass. Full suites and platform validation are running in hosted CI for this head; the earlier counts above remain historical.

@Byron Byron mentioned this pull request Oct 7, 2026
1 task
@Byron
Byron force-pushed the gix-backend branch 4 times, most recently from 594e7dd to 105114d Compare October 7, 2026 13:25
Byron pushed a commit that referenced this pull request Oct 7, 2026
PR #2274's Python 3.12 CI jobs spent 57m 25s in Windows `pytest` versus 5m 2s
on Ubuntu, with 85,777 and 82,683 `Git.execute` launches respectively. A local
profile of the file-handle and recursive submodule regressions spent about 65 of
77 seconds executing Git, including 44 seconds in repository construction.
Repeated process startup makes the separate metadata probes expensive.

Query reference format, object format, bare status and the absolute common
directory in one `git rev-parse` call on the CLI construction path. Keep the
path last and split only the three fixed scalar fields so embedded newlines
remain intact. Git still computes every value. Supported Gix discovery keeps
its native metadata and existing CLI format-validation query, with unchanged
native launch ceilings and fallbacks.

The focused selection drops from 2,447 to 2,009 launches: three saved for
each of 146 repository opens. Three paired Windows measurements of 20 opens
each reduce the median from 300.74 ms to 221.18 ms per open, with matching
metadata and 11 versus eight launches. Add `--durations=30` to CI so future
slow tests are visible, and record the profiling evidence and reproduction
requirements in `doc/gix-backend.md`.

Cover both object formats, both reference formats, bare and non-bare repos,
spaces and embedded newlines. The eight applicable Windows cases fail before
the fix and pass afterward; all 16 cases pass on Ubuntu WSL. The optional
Windows Gix selection reproduces the same 17 failures on the original and
patched sources. Document the demonstrated path-formatting and undecodable
`commondir` differences under `GIX-14`, distinguishing them from Windows test
assumptions. Keep these bugs open pending compatible upstream behavior.

Validation: the full Windows CLI suite passes with 1,662 passed, 60 skipped,
nine expected failures, two unexpected passes and 40 passing subtests. It
records 77,732 launches in 3,715.16s. The initial baseline records 86,032 in
3,990.28s; its only two failures pass on unchanged code after restoring CI's
`core.autocrlf=true` and placing `pytest`'s temporary directory outside a Git
checkout. The overlapping full runs are not a controlled elapsed-time
comparison. Repository-wide Ruff lint/format, all pinned pre-commit hooks,
`mypy` (47 files), `basedpyright` (zero errors or warnings), the Sphinx HTML
build and `git diff --check` pass.
Byron pushed a commit that referenced this pull request Oct 8, 2026
PR #2274's Python 3.12 CI jobs spent 57m 25s in Windows `pytest` versus 5m 2s
on Ubuntu, with 85,777 and 82,683 `Git.execute` launches respectively. A local
profile of the file-handle and recursive submodule regressions spent about 65 of
77 seconds executing Git, including 44 seconds in repository construction.
Repeated process startup makes the separate metadata probes expensive.

Query reference format, object format, bare status and the absolute common
directory in one `git rev-parse` call on the CLI construction path. Keep the
path last and split only the three fixed scalar fields so embedded newlines
remain intact. Git still computes every value. Supported Gix discovery keeps
its native metadata and existing CLI format-validation query, with unchanged
native launch ceilings and fallbacks.

The focused selection drops from 2,447 to 2,009 launches: three saved for
each of 146 repository opens. Three paired Windows measurements of 20 opens
each reduce the median from 300.74 ms to 221.18 ms per open, with matching
metadata and 11 versus eight launches. Add `--durations=30` to CI so future
slow tests are visible, and record the profiling evidence and reproduction
requirements in `doc/gix-backend.md`.

Cover both object formats, both reference formats, bare and non-bare repos,
spaces and embedded newlines. The eight applicable Windows cases fail before
the fix and pass afterward; all 16 cases pass on Ubuntu WSL. The optional
Windows Gix selection reproduces the same 17 failures on the original and
patched sources. Document the demonstrated path-formatting and undecodable
`commondir` differences under `GIX-14`, distinguishing them from Windows test
assumptions. Keep these bugs open pending compatible upstream behavior.

Validation: the full Windows CLI suite passes with 1,662 passed, 60 skipped,
nine expected failures, two unexpected passes and 40 passing subtests. It
records 77,732 launches in 3,715.16s. The initial baseline records 86,032 in
3,990.28s; its only two failures pass on unchanged code after restoring CI's
`core.autocrlf=true` and placing `pytest`'s temporary directory outside a Git
checkout. The overlapping full runs are not a controlled elapsed-time
comparison. Repository-wide Ruff lint/format, all pinned pre-commit hooks,
`mypy` (47 files), `basedpyright` (zero errors or warnings), the Sphinx HTML
build and `git diff --check` pass.
Byron pushed a commit that referenced this pull request Oct 8, 2026
PR #2274's Python 3.12 CI jobs spent 57m 25s in Windows `pytest` versus 5m 2s
on Ubuntu, with 85,777 and 82,683 `Git.execute` launches respectively. A local
profile of the file-handle and recursive submodule regressions spent about 65 of
77 seconds executing Git, including 44 seconds in repository construction.
Repeated process startup makes the separate metadata probes expensive.

Query reference format, object format, bare status and the absolute common
directory in one `git rev-parse` call on the CLI construction path. Keep the
path last and split only the three fixed scalar fields so embedded newlines
remain intact. Git still computes every value. Supported Gix discovery keeps
its native metadata and existing CLI format-validation query, with unchanged
native launch ceilings and fallbacks.

The focused selection drops from 2,447 to 2,009 launches: three saved for
each of 146 repository opens. Three paired Windows measurements of 20 opens
each reduce the median from 300.74 ms to 221.18 ms per open, with matching
metadata and 11 versus eight launches. Add `--durations=30` to CI so future
slow tests are visible, and record the profiling evidence and reproduction
requirements in `doc/gix-backend.md`.

Cover both object formats, both reference formats, bare and non-bare repos,
spaces and embedded newlines. The eight applicable Windows cases fail before
the fix and pass afterward; all 16 cases pass on Ubuntu WSL. The optional
Windows Gix selection reproduces the same 17 failures on the original and
patched sources. Document the demonstrated path-formatting and undecodable
`commondir` differences under `GIX-14`, distinguishing them from Windows test
assumptions. Keep these bugs open pending compatible upstream behavior.

Validation: the full Windows CLI suite passes with 1,662 passed, 60 skipped,
nine expected failures, two unexpected passes and 40 passing subtests. It
records 77,732 launches in 3,715.16s. The initial baseline records 86,032 in
3,990.28s; its only two failures pass on unchanged code after restoring CI's
`core.autocrlf=true` and placing `pytest`'s temporary directory outside a Git
checkout. The overlapping full runs are not a controlled elapsed-time
comparison. Repository-wide Ruff lint/format, all pinned pre-commit hooks,
`mypy` (47 files), `basedpyright` (zero errors or warnings), the Sphinx HTML
build and `git diff --check` pass.
@Byron
Byron force-pushed the gix-backend branch 4 times, most recently from af1de6a to c3a2832 Compare October 8, 2026 07:14
Byron pushed a commit that referenced this pull request Oct 9, 2026
PR #2274's Python 3.12 CI jobs spent 57m 25s in Windows `pytest` versus 5m 2s
on Ubuntu, with 85,777 and 82,683 `Git.execute` launches respectively. A local
profile of the file-handle and recursive submodule regressions spent about 65 of
77 seconds executing Git, including 44 seconds in repository construction.
Repeated process startup makes the separate metadata probes expensive.

Query reference format, object format, bare status and the absolute common
directory in one `git rev-parse` call on the CLI construction path. Keep the
path last and split only the three fixed scalar fields so embedded newlines
remain intact. Git still computes every value. Supported Gix discovery keeps
its native metadata and existing CLI format-validation query, with unchanged
native launch ceilings and fallbacks.

The focused selection drops from 2,447 to 2,009 launches: three saved for
each of 146 repository opens. Three paired Windows measurements of 20 opens
each reduce the median from 300.74 ms to 221.18 ms per open, with matching
metadata and 11 versus eight launches. Add `--durations=30` to CI so future
slow tests are visible, and record the profiling evidence and reproduction
requirements in `doc/gix-backend.md`.

Cover both object formats, both reference formats, bare and non-bare repos,
spaces and embedded newlines. The eight applicable Windows cases fail before
the fix and pass afterward; all 16 cases pass on Ubuntu WSL. The optional
Windows Gix selection reproduces the same 17 failures on the original and
patched sources. Document the demonstrated path-formatting and undecodable
`commondir` differences under `GIX-14`, distinguishing them from Windows test
assumptions. Keep these bugs open pending compatible upstream behavior.

Validation: the full Windows CLI suite passes with 1,662 passed, 60 skipped,
nine expected failures, two unexpected passes and 40 passing subtests. It
records 77,732 launches in 3,715.16s. The initial baseline records 86,032 in
3,990.28s; its only two failures pass on unchanged code after restoring CI's
`core.autocrlf=true` and placing `pytest`'s temporary directory outside a Git
checkout. The overlapping full runs are not a controlled elapsed-time
comparison. Repository-wide Ruff lint/format, all pinned pre-commit hooks,
`mypy` (47 files), `basedpyright` (zero errors or warnings), the Sphinx HTML
build and `git diff --check` pass.
@Byron
Byron force-pushed the gix-backend branch 4 times, most recently from 75ebc93 to 6881712 Compare October 9, 2026 08:01
Byron pushed a commit that referenced this pull request Oct 9, 2026
The Windows Python 3.14 job for PR #2274 failed in
`TestSubmodule.test_base_rw` when forced module-only removal called
`rmtree`: Windows reported `WinError 32` for `git/ext/gitdb`.
The legacy test retains that checkout's `Repo` through `csm.repo` and
starts its persistent `cat-file` process while reading parent commits.
Closing only the fresh handle created by `Submodule.remove()` cannot
release this caller-owned process.

Close the retained test-owned parent before deleting its checkout. Keep
strict removal and all existing happy-path assertions, and remove the
obsolete commented-out skip that claimed removal ignored this error.
The original test predates the PR's base, so record this as a follow-up
rather than rewriting shared history.

The focused `test_base_rw` passed locally with both CLI and Gix.
Relevant pre-commit hooks passed. Hosted Windows validation remains
part of the PR CI loop.
Byron pushed a commit that referenced this pull request Oct 9, 2026
The Windows Python 3.14 job for PR #2274 failed in
`TestSubmodule.test_base_rw` when forced module-only removal called
`rmtree`: Windows reported `WinError 32` for `git/ext/gitdb`.
The legacy test retains that checkout's `Repo` through `csm.repo` and
starts its persistent `cat-file` process while reading parent commits.
Closing only the fresh handle created by `Submodule.remove()` cannot
release this caller-owned process.

Close the retained test-owned parent before deleting its checkout. Keep
strict removal and all existing happy-path assertions, and remove the
obsolete commented-out skip that claimed removal ignored this error.
The original test predates the PR's base, so record this as a follow-up
rather than rewriting shared history.

The focused `test_base_rw` passed locally with both CLI and Gix.
Relevant pre-commit hooks passed. Hosted Windows validation remains
part of the PR CI loop.
@Byron
Byron force-pushed the gix-backend branch 2 times, most recently from 17a316c to a6c7dba Compare October 14, 2026 09:31
Byron pushed a commit that referenced this pull request Oct 14, 2026
PR #2274's Python 3.12 CI jobs spent 57m 25s in Windows `pytest` versus 5m 2s
on Ubuntu, with 85,777 and 82,683 `Git.execute` launches respectively. A local
profile of the file-handle and recursive submodule regressions spent about 65 of
77 seconds executing Git, including 44 seconds in repository construction.
Repeated process startup makes the separate metadata probes expensive.

Query reference format, object format, bare status and the absolute common
directory in one `git rev-parse` call on the CLI construction path. Keep the
path last and split only the three fixed scalar fields so embedded newlines
remain intact. Git still computes every value. Supported Gix discovery keeps
its native metadata and existing CLI format-validation query, with unchanged
native launch ceilings and fallbacks.

The focused selection drops from 2,447 to 2,009 launches: three saved for
each of 146 repository opens. Three paired Windows measurements of 20 opens
each reduce the median from 300.74 ms to 221.18 ms per open, with matching
metadata and 11 versus eight launches. Add `--durations=30` to CI so future
slow tests are visible, and record the profiling evidence and reproduction
requirements in `doc/gix-backend.md`.

Cover both object formats, both reference formats, bare and non-bare repos,
spaces and embedded newlines. The eight applicable Windows cases fail before
the fix and pass afterward; all 16 cases pass on Ubuntu WSL. The optional
Windows Gix selection reproduces the same 17 failures on the original and
patched sources. Document the demonstrated path-formatting and undecodable
`commondir` differences under `GIX-14`, distinguishing them from Windows test
assumptions. Keep these bugs open pending compatible upstream behavior.

Validation: the full Windows CLI suite passes with 1,662 passed, 60 skipped,
nine expected failures, two unexpected passes and 40 passing subtests. It
records 77,732 launches in 3,715.16s. The initial baseline records 86,032 in
3,990.28s; its only two failures pass on unchanged code after restoring CI's
`core.autocrlf=true` and placing `pytest`'s temporary directory outside a Git
checkout. The overlapping full runs are not a controlled elapsed-time
comparison. Repository-wide Ruff lint/format, all pinned pre-commit hooks,
`mypy` (47 files), `basedpyright` (zero errors or warnings), the Sphinx HTML
build and `git diff --check` pass.
Byron pushed a commit that referenced this pull request Oct 14, 2026
The Windows Python 3.14 job for PR #2274 failed in
`TestSubmodule.test_base_rw` when forced module-only removal called
`rmtree`: Windows reported `WinError 32` for `git/ext/gitdb`.
The legacy test retains that checkout's `Repo` through `csm.repo` and
starts its persistent `cat-file` process while reading parent commits.
Closing only the fresh handle created by `Submodule.remove()` cannot
release this caller-owned process.

Close the retained test-owned parent before deleting its checkout. Keep
strict removal and all existing happy-path assertions, and remove the
obsolete commented-out skip that claimed removal ignored this error.
The original test predates the PR's base, so record this as a follow-up
rather than rewriting shared history.

The focused `test_base_rw` passed locally with both CLI and Gix.
Relevant pre-commit hooks passed. Hosted Windows validation remains
part of the PR CI loop.
Copilot AI mentioned this pull request Oct 14, 2026
@Byron
Byron force-pushed the gix-backend branch 4 times, most recently from 13202ce to 781c620 Compare October 15, 2026 08:53
codex added 17 commits October 24, 2026 22:07
angr 10.0.4.post1's repository report cannot describe a branch configured to
track another local branch. `Head.tracking_branch()` treats Git's special
`branch.<name>.remote=.` value as a remote name and constructs the nonexistent
`refs/remotes/./<branch>` reference. The helper prints a generic tracking error
instead of its intended local-branch message. Released GitPython 3.2.1 exhibits
the same bug; a valid local-upstream fixture reproduces it independently.

For the local-repository selector, ask `git rev-parse --symbolic-full-name
<branch>@{upstream}` to resolve the configured location and return a `Head` for
that result. Keep existing remote-reference behavior for ordinary remote
tracking. Update the annotated return type and documentation for local heads.
This delegates Git configuration and upstream validation to Git rather than
reconstructing their semantics in Python. GixPython does not expose this resolver,
so the operation retains an explicit documented CLI fallback.

Add a Bash fixture and regressions across SHA-1/SHA-256 and files/reftable
storage. All four cases fail before the correction. The full reference suite
and downstream regressions pass 61 tests and 24 subtests on each backend, CLI
first. All five unchanged angr supplemental tests now pass on both backends;
the initial and released baseline failures are retained in the audit evidence.
Ruff lint/format, ShellCheck for the fixture, mypy for `git/refs/head.py` and
`git diff --check` pass with Python 3.12.15, Git 2.53.0 and GixPython 0.2.0.
MCP Server Git 2026.10.19's unchanged suite exposes three regressions in
`Repo.rev_parse()`: `HEAD:` returns a root `Tree` without a path, so directory
listing fails, and a missing `HEAD:<path>` raises generic `BadName` instead of
the established tree lookup `KeyError`. All three tests pass with released
GitPython 3.2.1 and fail with both local backends before this correction.

Retain an empty path for successfully resolved root trees when Git's
`objectmode` atom or Gix's `RevisionSpec.path_and_mode()` omits that context.
Factor the existing Git-validated colon boundary query so missing paths use
the public backend-managed `Tree.join()` for missing-component diagnostics,
including nested paths and colons inside commit-message searches. Git/Gix
continue to resolve revisions and read trees; no storage or Git semantics are
implemented separately in Python. The diagnostic prefix resolver retains a
documented CLI fallback until GixPython exposes compatible failed-path context.

Add a scripted fixture and eight regression cases across SHA-1/SHA-256 and
files/reftable; all eight fail before the correction. The repository/revision
and downstream suites pass 184 tests, two skips and 14 subtests on CLI; adding
native backend parity tests passes 286 tests, two skips and 14 subtests on Gix.
MCP Server Git's full unchanged suite now passes all 186 tests on each backend.
Ruff lint/format, ShellCheck for the fixture, mypy for `git/repo/fun.py`, and
`git diff --check` pass with Python 3.12.15, Git 2.53.0 and GixPython 0.2.0.
sbxloop 2.1.36 explicitly opens its metadata repositories with
`Repo(..., expand_vars=False)` to keep repository paths literal. Removing the
constructor option during the storage migration breaks 91 unchanged upstream
cases before their Git queries run. Released GitPython 3.2.1 accepts the option.

Restore the `False` constructor argument, including its fourth positional
location, while retaining the branch's default literal environment-variable
behavior. Reject `True` with a clear `ValueError` directing callers to expand
inputs themselves. Initial tilde expansion and Git/Gix discovery remain as
before; this input compatibility does not restore automatic environment
expansion or introduce Python Git behavior. Document the limited restored
contract and the remaining breaking path/API behavior.

Add a fixture containing both a literal `$DOWNSTREAM_REPOSITORY` repository
and an expansion target. Four SHA-1/SHA-256 and files/reftable regressions fail
before the correction and verify literal contents, keyword/positional use,
the unchanged default, and rejected expansion afterwards. Repository, CLI
safety and downstream suites pass 189 tests, two skips and 14 subtests on each
backend. Ruff lint/format, ShellCheck for the fixture, mypy for
`git/repo/base.py` and `git diff --check` pass with Python 3.12.15,
Git 2.53.0 and GixPython 0.2.0.
Salt parses `git.__version__` when enabling its GitPython provider. Source
imports retain the build placeholder `"git"`, so an editable installation
reports valid distribution metadata but Salt rejects the provider and skips
its real fileserver tests.

Read the checkout's `VERSION` only when the public value is still unstamped.
Built wheels and source distributions continue to use the existing release
stamping; repository discovery and backend selection are unchanged.

The regression failed with `"git"` before this change. All 34 downstream
compatibility regressions pass with both CLI and Gix. Ruff lint/format,
mypy for `git/__init__.py`, and `git diff --check` pass.
Demisto SDK imports `Union` from `git` while registering validators. Released
GitPython exposes `typing.Union`; removing that incidental export prevents
its unchanged root test conftest and CLI command registration from importing.

Retain the explicit alias without changing wildcard exports or adding Git
behavior. This unblocks the existing caller while preserving the narrower
package namespace elsewhere.

The import regression failed before this change. All 35 downstream
compatibility cases pass on CLI and Gix. Ruff lint/format, mypy for
`git/__init__.py`, and `git diff --check` pass. Released GitPython 3.2.1
was force-installed and verified in site-packages for the downstream baseline.
The existing release stamper matches every line containing `__version__ =`.
A comparison with the version variable on the left is also matched, causing
it to replace the placeholder in the new editable-import guard. That would
incorrectly enable the source-tree `VERSION` lookup in a built wheel, which
does not ship that file.

Put the literal on the left of the guard so stamping changes only the public
assignment. Extend the existing isolated installation test to verify public
version parity with the running source checkout.

The isolated installation and version checks pass with both CLI and Gix;
Ruff lint/format and `git diff --check` pass. The full CLI suite also passes:
1,827 passed,162 skipped,1 xfailed and59 passed subtests.
Kas 5.5 temporarily changes Git identity and restores it with
`config["user"] = original_values`. The migrated parser removed inherited
mapping assignment, leaving cleanup broken although released GitPython 3.2.1
passes that exact caller check.

Validate the complete nonempty mapping before changing the file, then use
existing Git config section removal and value writes. This replaces duplicate
and obsolete options while retaining other sections. Each Git mutation locks
independently; replacement is not transaction-wide atomic.

Empty sections and `add_section()` remain unsupported by the available native
configuration APIs. Kas's three SSH validation failures are retained and
documented alongside the existing Airflow mirror-fetch adapter gap. No Git
serialization or successful empty-section result is implemented in Python.

All four new SHA-1/SHA-256, files/reftable regressions failed before the fix.
All 90 config/downstream cases pass on CLI and Gix; Ruff lint/format, mypy for
`git/config.py`, and `git diff --check` pass.

The PR #2274 Python 3.8 install/import checks failed on Linux, macOS and
Windows with `TypeError: 'ABCMeta' object is not subscriptable` while evaluating
`Mapping[str, Any]`. Import `Mapping` from `typing`, preserving the same runtime
mapping validation while supporting the declared Python 3.8 minimum. The source
import reproduced the failure before this correction and passes afterward with
Python 3.8.20, including evaluated method annotations. The config/downstream
modules pass all 90 tests on each backend; Ruff lint/format and changed-module
mypy pass. Hosted verification follows the branch push.
MkDocs RSS Plugin 1.19.0 imports `Optional` from `git` while importing its
actual utility module. Released GitPython 3.2.1 exposes `typing.Optional`,
whereas the migrated package renamed that import and prevents the plugin
from loading.

Restore the explicit public alias and use it for the existing `refresh()`
annotation. Wildcard exports and Git operations are unchanged.

The new import regression fails before the fix. All 40 downstream
compatibility cases pass on CLI and Gix; Ruff lint/format, mypy for
`git/__init__.py`, and `git diff --check` pass. A forced released baseline
proves the alias and actual plugin import in site-packages.
Port the regression from PR #2302 using the scripted repository fixtures.
Check ordinary, Unicode, DEL-containing and leading-space filenames with
both `core.quotePath` settings, including untracked dirty detection.

Validate every filename against NUL-delimited `git status` output before
querying GitPython. Both backends already preserve these paths: the CLI
uses NUL records and Gix uses its directory walk, so no production fix is
needed.

Both untracked-file tests pass with CLI and Gix, including two configuration
subtests. Ruff lint/format, ShellCheck and `git diff --check` pass.
Port PR #2301's regression for U+0085, U+2028 and U+2029 in filenames
with `core.quotePath=false`. Both backends raised `ValueError` because
`Commit.stats` and `Stats._list_from_string()` treated those characters as
record separators in Git's output.

Split only at LF and ignore empty records, preserving filenames and empty
commit results. Keep the existing Gix filename-quoting CLI fallback; this
change adapts Git's output and does not implement native diff behavior.
Clarify that fallback in `doc/gix-backend.md` and record the user-visible fix.

The scripted fixture creates root, modified and empty commits through Git.
Direct NUL-delimited `git diff-tree --numstat` and `--name-status` queries
validate the expected names, counts and change types before the GitPython
assertions. The regression fails before the fix with both backends; all 42
commit/statistics tests and 21 subtests pass afterward on each backend.
Ruff lint/format, changed-source mypy, ShellCheck and `git diff --check` pass.
Cover the configuration regressions from PRs #2305 and #2307 against actual
`git config` output. The current configuration facade already delegates
these operations to Git, so the valid cases pass without a runtime change.

Use scripted fixtures for a real home-relative conditional include and the
complete inline-header sample. Preserve native `HOME` and `USERPROFILE`
separators so the same test exercises the Windows path case on Windows.
Check both matching and nonmatching repositories and file/stream readers.
Also check adjacent headers, an escaped quote before `]`, and rejection of
unbalanced quotes, missing/stray brackets, malformed keys and sections.

Git accepts multiple section headers on one line but omits empty sections
from `git config list`. Reflect that output and the facade's documented
empty-section limitation instead of restoring a separate Python parser.
Document the existing `GIX-12` fallback without claiming native coverage.

Validation on macOS, Git 2.54.0, Python 3.12 and GixPython 0.2.0:

- All 11 added cases passed against the unchanged runtime.
- `test/test_config.py`: 62 passed with each of the CLI and Gix backends.
- `ruff check`, `ruff format --check`, `bash -n` and `git diff --check` passed.

Windows and Linux execution was not available for this local check.
Port the regression from PR #2303 for CR-only, space-only and tab-only
header lines. Each initial commit is created by `commit.sh`, accepted by
`git fsck --strict`, and projected by `git show` before comparing both
`Commit._deserialize()` and the public lazy commit reader. A forged
`Co-authored-by` header must stay outside the message and co-author list.

The existing LF-only header parser already passes these cases, so no
production fix is needed. Record GIX-31: GixPython 0.2.0 rejects CR/tab
header lines that Git 2.54.0 accepts. The tests preserve and verify the
existing native decoder diagnostic fallback; the space continuation
uses the existing GIX-30 late-encoding fallback.

Validation: all 41 tests and 24 subtests in `test/test_commit.py` pass
with both `GIT_PYTHON_BACKEND=cli` and `GIT_PYTHON_BACKEND=gix`.
`ruff check`, `bash -n` and `git diff --check` pass.
URLs read from `.gitmodules` were cloned and fetched as if a user had
provided them directly. Git rejects `protocol.file.allow=user` for
`git submodule update`, but `Submodule.update` accepted it on both backends.

Port the clone/fetch regression from PR #2304, with a scripted initial
state and live `git submodule update --init` / `--remote` baselines for
denied transfers, allowed transfers, and checked-out commits. Pass
`GIT_PROTOCOL_FROM_USER=0` to these CLI operations. Preserve the existing
explicit unsafe-protocol option and caller-provided clone environment.
Move the existing test config helper so local-submodule tests and tutorials
can request `protocol.file.allow=always` explicitly.

The regression failed on both backends before this change and passes on
both afterward against Git 2.54.0 and GixPython 0.2.0. The submodule,
no-fetch, and docs suites exercised 482 cases per backend; all 476 expected
passing cases passed after the affected docs fixture and host-signing case
were rerun with the isolated runner (5 skips, 1 expected failure).
Ruff lint/format, shellcheck, and `git diff --check` pass. Clone and fetch
remain CLI fallbacks; document the native API gaps without claiming Gix
implements the transport operation.
`RootModule.update` fetches a temporary remote when `.gitmodules` changes a
submodule URL. That fetch still treated the URL as user-provided, even after
ordinary submodule clone/fetch gained Git's non-user transport environment.
It could therefore access a denied local repository and replace `origin`
before the subsequent ordinary fetch finally rejected the transport.

Port PR #2304's separate changed-URL regression and apply the existing
`_transport_env()` helper to that initial fetch. The test compares denial
with real `git submodule sync` / `update --remote`, and checks unchanged
HEAD and original-remote preservation against a rejected Git fetch. Its
location-dependent initial repositories use the shared scripted fixtures.

Both source regressions failed on the original CLI and Gix backends. The
changed-URL test also failed independently after the ordinary update fix,
because `origin` had already changed. After this fix, 17 focused transport,
root-update, and no-fetch cases pass on each backend under the isolated
runner, using Git 2.54.0 and GixPython 0.2.0. Ruff lint/format, shellcheck,
and `git diff --check` pass. The fetch remains an explicit CLI operation.
Port PR #2306's regression against direct `git commit` and `git hook`
invocations. Before this fix, `Repo`'s automatic `GIT_DIR` binding made
Git treat the repository as explicitly selected: `IndexFile.commit()`
ran its pre-commit hook even when ordinary Git rejected dubious
ownership. The regression fails on both backends without the fix.

Retain the original discovery location and run `git rev-parse --git-dir`
before executing any commit hook, removing only the automatically bound
environment values. Remembering discovery supports external
`core.worktree` locations while matching `safe.directory` on ordinary,
bare, linked and separate-directory repositories. Explicit environment
or command-line repository selections retain Git's behavior, including
relative paths and consumption of one-shot options after failures.
Validate NUL arguments before starting either process.

The fixture tests verify rejection without hook side effects, Git's
safe-directory exemptions, and explicit repository-selection behavior.
Update the native-backend coverage test and GIX-23 documentation to
require two CLI processes per valid hook request, including missing
hooks. No independent ownership policy or native hook implementation
is introduced.

Validation: before the final option-preservation refinements, the full
index, repository and backend modules passed (CLI: 236 tests, 106 skips;
Gix: 338 tests, 4 skips; each with 19 passing subtests). Final focused
hook coverage passes with CLI (12 tests, 2 skips) and Gix (14 tests),
each with 9 passing subtests. A separate review independently reran the
ownership and repository-selection regressions on both backends.
`ruff check`, targeted `mypy`, fixture `bash -n` and `git diff --check`
pass. Windows and Linux were not run locally.
The five automated downstream profiles do not describe GitPython's wider
runtime, development and documentation consumers. Record four completed audit
batches of 31, 30, 39 and 15 distinct projects selected from September 2026
PyPI downloads plus known Git-focused users. The inventory covers every
identified current declared consumer within the top-15,000 snapshot and
348,530,835 monthly distribution requests, including extras. Downloads are
neither unique users nor attributable GitPython installations; the additions
and metadata limits also prevent a strict popularity top-115 claim.

Retain all four reports and JSON manifests under `test/downstream/`, linked
from its README. Preserve release and archive provenance, commands, import
proofs, backend results, baseline comparisons and coverage limits at their
original tested revisions. Sources, environments, logs, JUnit XML and
supplemental runners remain in ignored audit caches; a fresh environment must
reconstruct the disclosed harness. The five-profile CI runner remains the
maintained automation. Upstream tests, mocks and expectations are unchanged;
selected helpers, unused declarations and omitted application stacks are
identified explicitly. Gix selections retain documented Git CLI fallbacks.

Twelve separate fixes restore immutable index readers, global `-C` selection,
separate-Git-directory context, the `GitDB` selector, local tracking branches,
revision tree/path diagnostics, explicit literal-path construction, editable
version reporting, built-wheel version isolation, historical `Union` and
`Optional` imports, and nonempty configuration-section assignment.

Keep the remaining compatibility work visible. Kas 5.5 has three SSH setup
failures because `add_section()` cannot create an empty section through the
supported native APIs; downstream can use `set_value()` directly, while full
compatibility requires a native section-edit API. sbxloop 2.1.36 has five
constructor-subclass failures because native discovery validates metadata
before its overridden `config_reader()` runs; restoring that view requires
supported discovery/include controls without bypassing Git format validation.
Index mapping mutation and automatic environment expansion remain unsupported.
Airflow's ambiguous bare/mirror fetch results expose a separate GitPython
adapter gap: Git `fetch --porcelain` supplies full destination identities for
a future CLI adapter fix; Gix fetch remains a fallback until per-ref outcomes
are exposed. Other retained failures are downstream defects, baseline behavior
or explicitly recorded harness/coverage limits, not passing results.

Historical final full suites after the last production fix recorded 1,832
CLI passes and 1,934 Gix passes, with 162/60 skips, one xfail and 59 passed
subtests each. The last batch adds 117 upstream and 187 supplemental passes,
one baseline-inherited Dstack failure and two Jira skips per backend; its
separate MkNotebooks Binder build passes with both backends and the release.
Those historical results are not reruns on this rewritten stack.

Consolidate the four `docs:` record commits at the stack tip while retaining
the feature commit and twelve fixes in their original order. Resolve only
changelog context conflicts, keeping implementation entries with their fixes
and the subclass record here. Verify an identical final tree, unchanged
non-documentation patches, fourteen final commits with one top `docs:` commit,
115 distinct manifest projects, recorded CLI/Gix parity, local report links
and `git diff --check`. No new tests or hosted CI were run and no push occurred.
Replace the historical Gitoxide introduction in `README.md` with an
explanation of `GixPython` as Gitoxide's Python bindings and the experimental
`GitPython` backend. Describe reduced subprocess overhead and reuse of the
native repository handle, with a link to the backend benchmarks.

Show installation from this unreleased source checkout and selection through
`GIT_PYTHON_BACKEND` before imports. Explain automatic selection, explicit
CLI/Gix choices, CPython 3.11+, Git 2.52+, and the Rust 1.89+ and system linker
needed for Linux and Windows source builds of `GixPython` 0.3.0. Its default
hashing, compression and HTTPS dependencies use pure Rust. Retain CLI fallback
and compatibility limitations, linking the backend ledger and downstream audit.

Resolve replay against the introducing commit's 0.3.0 upgrade by keeping the
new README structure while updating its package version and source-build
prerequisites. No repository implementation changes are part of this commit.

Validation: the README activation example returned the same HEAD as
`git rev-parse HEAD`; local links and `git diff --check` passed. The complete
fast profile passed: configured pre-commit hooks, `mypy --python-version=3.12`,
`basedpyright --warnings`, `uv sync --all-extras --all-groups --dry-run`, and
vendored-package CI lint. Full tests, builds, documentation builds and
benchmarks were outside the requested fast profile.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved object-decoding and branch-renaming errors can return incomplete data or references to the wrong branch.

3 open issues
What changed in this PR

GitHub Copilot review: This PR prepares GitPython for newer Git storage formats and adds an optional GixPython backend, supported by shared fixtures, compatibility checks, and benchmarks.

Changes:

  • Delegate storage operations to guarded Git commands or supported Gix APIs, with updated object IDs and index interfaces.
  • Introduce reusable scripted fixtures, backend reporting, downstream checks, and benchmark parity enforcement.
  • Update installation guidance, dependencies, CI, and fuzzing for Git 2.52+.
File Description
tox.ini Select backends and add older-runtime smoke checks.
tests/​fixtures/​util.sh Prepare lock and symlink scenarios.
tests/​fixtures/​tree-order.sh Capture Git tree ordering.
tests/​fixtures/​submodule-transport.sh Prepare submodule transport comparisons.
tests/​fixtures/​submodule-symlinks.sh Prepare checkout and metadata symlinks.
tests/​fixtures/​submodule-special.sh Cover special submodule layouts and names.
tests/​fixtures/​submodule-source.sh Create a reusable submodule source.
tests/​fixtures/​submodule-relative.sh Prepare relative-URL scenarios.
tests/​fixtures/​submodule-no-fetch.sh Prepare offline submodule updates.
tests/​fixtures/​submodule-layout.sh Build varied submodule layouts.
tests/​fixtures/​submodule-cases.sh Prepare submodule lifecycle and safety cases.
tests/​fixtures/​safety.sh Prepare command and object safety cases.
tests/​fixtures/​rmtree.sh Prepare deletion and permission scenarios.
tests/​fixtures/​rev-parse.sh Build revision-parsing histories.
tests/​fixtures/​remote-timeout.sh Create a timeout-test repository.
tests/​fixtures/​remote-cli.sh Prepare fetch and quoted-name scenarios.
tests/​fixtures/​refs.sh Prepare reference safety cases.
tests/​fixtures/​refs-input.sh Create option-injection inputs.
tests/​fixtures/​reflog.sh Prepare reflog and signing scenarios.
tests/​fixtures/​reference-security.sh Build cyclic and external reference cases.
tests/​fixtures/​quick-doc.sh Replace remote tutorial setup locally.
tests/​fixtures/​positional.sh Prepare option-shaped operand cases.
tests/​fixtures/​objects-index.sh Prepare object, index, and hook scenarios.
tests/​fixtures/​local-environment.sh Generate isolated test configuration.
tests/​fixtures/​installation.sh Prepare installation-test environments.
tests/​fixtures/​index.sh Build index and hook fixtures.
tests/​fixtures/​hook-ownership.sh Prepare hook ownership layouts.
tests/​fixtures/​history.sh Create historical repository layouts.
tests/​fixtures/​git-command.sh Prepare executable and environment cases.
tests/​fixtures/​fun.sh Construct merge-tree inputs.
tests/​fixtures/​fixture-lifecycle.sh Support fixture lifecycle checks.
tests/​fixtures/​empty.sh Supply empty directories or repositories.
tests/​fixtures/​downstream-worktree.sh Prepare downstream worktree cases.
tests/​fixtures/​downstream-swebench.sh Create local SWE-bench clone sources.
tests/​fixtures/​downstream-separate-git-dir.sh Create relocatable separate metadata.
tests/​fixtures/​downstream-revision-path.sh Prepare revision-path compatibility cases.
tests/​fixtures/​downstream-local-upstream.sh Configure local tracking branches.
tests/​fixtures/​downstream-literal-repo.sh Preserve literal variable-shaped paths.
tests/​fixtures/​downstream-index.sh Prepare immutable index-reader cases.
tests/​fixtures/​docs.sh Isolate tutorial push destinations.
tests/​fixtures/​diff.sh Prepare diff formats and edge cases.
tests/​fixtures/​dependencies.sh Create historical dependency repositories.
tests/​fixtures/​config.sh Prepare configuration parsing cases.
tests/​fixtures/​commit.sh Prepare commit metadata and encoding cases.
tests/​fixtures/​command-guards.sh Prepare guarded-command regressions.
tests/​fixtures/​clone.sh Prepare clone compatibility cases.
tests/​fixtures/​cleanup.sh Prepare cleanup failure scenarios.
tests/​fixtures/​benchmark.sh Create the pinned benchmark repository.
tests/​fixtures/​benchmark-comparison.sh Generate comparison validation inputs.
test/​test_typing.py Update semantic index-entry checks.
test/​test_remote_progress.py Check progress override return typing.
test/​test_remote_cli.py Check command-derived fetch results.
test/​test_quick_doc.py Use local tutorial fixtures.
test/​test_installation.py Check installation, backend, and version behavior.
test/​test_imports.py Check the actual utility-module binding.
test/​test_fixture_health.py Check fixture reuse, isolation, and errors.
test/​test_exc.py Remove unnecessary repository setup.
test/​test_docs.py Isolate tutorials and update index examples.
test/​test_cli_process_counts.py Check subprocess counters and ceilings.
test/​test_blob_filter.py Simplify blob-filter inputs.
test/​test_base.py Move setup into shared fixtures.
test/​test_backend_selection.py Check backend selection and fixture availability.
test/​test_actor.py Remove obsolete deprecation checks.
test/​run-local.py Add isolated local test execution.
test/​performance/​test_odb.py Remove legacy object-store timing tests.
test/​performance/​test_commit.py Remove legacy commit timing tests.
test/​performance/​test_benchmark_comparison.py Check benchmark parity enforcement.
test/​performance/​README.md Document benchmark execution and interpretation.
test/​performance/​lib.py Remove legacy performance helpers.
test/​performance/​compare_backends.py Validate parity and report measurements.
test/​performance/​cli-budget.json Define backend subprocess ceilings.
test/​performance/​benchmark-requirements.txt Declare benchmark dependencies.
test/​lib/​fixtures.py Manage cached and writable scripted fixtures.
test/​downstream/​projects.json Define downstream compatibility profiles.
test/​downstream/​checks/​swebench.py Exercise real SWE-bench GitPython callers.
test/​deprecation/​test_types.py Remove obsolete type-alias deprecation tests.
test/​deprecation/​test_compat.py Remove platform-alias deprecation tests.
test/​deprecation/​test_basic.py Remove obsolete deprecation coverage.
test/​deprecation/​lib.py Remove deprecation test helpers.
test/​deprecation/​__init__.py Remove the deprecation test package.
test/​conftest.py Report backend operations and fixture sources.
test/​cleanup.py Add best-effort test-directory cleanup.
test-requirements.txt Add GixPython fixture tooling.
README.md Explain Gix activation and prerequisites.
pyproject.toml Add the Gix extra and adjust typing coverage.
MANIFEST.in Package Gix requirements and exclude fixtures.
gix-requirements.txt Pin the optional GixPython dependency.
git/​types.py Remove the deprecated commit-type alias.
git/​refs/​tag.py Guard tag options and validate operands.
git/​refs/​remote.py Delegate reference deletion to Git.
git/​refs/​reference.py Let Git maintain HEAD reflogs.
git/​refs/​head.py Guard branch operations and support local upstreams.
git/​objects/​util.py Delegate textual date parsing to Git.
git/​objects/​tree.py Delegate tree loading and construction to Git.
git/​objects/​tag.py Add native tag metadata decoding.
git/​objects/​submodule/​util.py Use shared configuration-section escaping.
git/​objects/​submodule/​root.py Update reflog lookup and transport handling.
git/​objects/​base.py Support repository-specific object ID widths.
git/​index/​util.py Remove obsolete binary-index helpers.
git/​index/​typ.py Represent semantic index entries without raw metadata.
git/​diff.py Add native dispatch and guarded CLI diffs.
git/​compat.py Remove deprecated platform aliases.
git/​__init__.py Update version loading and compatibility exports.
fuzzing/​README.md Document Git-backed fuzzing requirements.
fuzzing/​oss-fuzz-scripts/​container-environment-bootstrap.sh Enforce the minimum Git version.
fuzzing/​oss-fuzz-scripts/​build.sh Validate and bundle the selected Git executable.
fuzzing/​local-dev-helpers/​Dockerfile Build the minimum supported Git.
fuzzing/​fuzz-targets/​fuzz_repo.py Exercise Git-backed repository workflows.
fuzzing/​fuzz-targets/​fuzz_diff.py Adapt object IDs and expected errors.
fuzzing/​fuzz-targets/​fuzz_config.py Handle expected Git configuration rejection.
fuzzing/​fuzz-targets/​fuzz_blob.py Respect repository object ID widths.
doc/​source/​tutorial.rst Update object, index, and reflog guidance.
doc/​source/​intro.rst Describe storage support and new requirements.
CONTRIBUTING.md Document fixture and cleanup conventions.
AGENTS.md Define Gix implementation and compatibility requirements.
.gitignore Ignore generated fixture caches and archives.
.github/​workflows/​git-cli.yml Test minimum-Git format and safety contracts.
.github/​workflows/​downstream.yml Run downstream profiles on both backends.
.github/​workflows/​cygwin-test.yml Build supported Git and smoke-test installation.
.github/​workflows/​backend-benchmark.yml Measure backends and enforce parity budgets.
.github/​workflows/​alpine-test.yml Install fixture tooling and select CLI explicitly.
.basedpyright/​baseline.json Remove obsolete typing suppressions.

Review effort: Balanced

Comment thread git/objects/tag.py
Comment thread git/objects/tree.py
Comment thread git/refs/head.py
@Byron
Byron merged commit f1fb0bd into main Oct 24, 2026
65 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants